package cn.jinbyte.web.serialize;

import cn.jinbyte.core.handler.crypt.CryptHandler;
import cn.jinbyte.core.helper.SpringContextHelper;
import cn.jinbyte.web.annotation.CryptProp;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;

import java.io.IOException;

/**
 * 密文字段反序列化
 *
 * @author jinty
 * @since 1.0.0
 */
@Slf4j
public class CryptPropDeserializer extends JsonDeserializer<Object>
        implements ContextualDeserializer {

    private JavaType javaType;
    private CryptProp annotation;

    @Override
    public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        String valueAsString = jsonParser.getValueAsString();
        Class<? extends CryptHandler> cryptHandlerClass = annotation.handler();
        CryptHandler bean = null;
        try {
            bean = SpringContextHelper.getBean(cryptHandlerClass);
        } catch (BeansException e) {
            log.error("Not Found CryptHandler: {}", cryptHandlerClass.getName());
        }
        if (bean == null) {
            return null;
        }
        return bean.decode(valueAsString, javaType.getRawClass());
    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext deserializationContext, BeanProperty beanProperty) throws JsonMappingException {
        CryptProp annotation = beanProperty.getAnnotation(CryptProp.class);
        if (annotation != null) {
            this.javaType = beanProperty.getType();
            this.annotation = annotation;
            return this;
        }
        return deserializationContext.findContextualValueDeserializer(beanProperty.getType(), beanProperty);
    }

}
